require("classes");

Class	{	"Board"
		,	tableName = String	-- since we don't support the data type "table" in our class concept, we have to save it global under this (unique) name
		}

function Board:create()
	self.tableName		= "board_" .. string.sub(tostring(self), 8)
	_G[self.tableName]	= {}

	local board = _G[self.tableName]
	for i = 1, 6, 1 do
		board[i] = {}
		for j = 1, 6, 1 do
			board[i][j] = 0
		end
	end
end



function Board:print()
	local board		= _G[self.tableName]
	local result	= "+-------+--------+\n"

	for i = 1, 6, 1 do

		local line = "|";

		for j = 1, 6, 1 do

			local field = board[i][j]
			if field == 0 then
				line = line .. '.'
			elseif field == 1 then
				line = line .. 'W'
			else
				line = line .. 'B'
			end

			if j == 3 or j == 6 then
				line = line .. "| "
			else
				line = line .. "  "
			end
		end

		result	= result .. line .. "\n";

		if i == 3 or i == 6 then
			result = result .. "+-------+--------+\n"
		else
			result = result .. "|       |        |\n"
		end
	end
	print (result);
end

function Board:set_stone(x, y, colour)
	local board = _G[self.tableName]
	--[[local position_mapping = {}
	for i = 1, 9, 1 do 

	if x == 'a' or x == 'A' then
]]
	board[x][y] = colour
end

function Board:get_stone(x, y)
	local board = _G[self.tableName]
	return board[x][y]
end

function Board:_turn_CW(square)
	local board		= _G[self.tableName]
	local temp_board = {}

	for i = 1, 6, 1 do
		temp_board[i] = {}
		for j = 1, 6, 1 do
			temp_board[i][j] = 0
		end
	end
	
	if square == 'A' or square=='a' then
		local A = {3,2,1}

		for i = 1, 3, 1 do
			for j = 1, 3, 1 do
				temp_board[j][A[i]] = board[i][j]
			end
		end
		for i = 1, 3, 1 do
			for j = 1, 3, 1 do
				board[i][j] = temp_board[i][j] 
			end
		end
	elseif square == 'B' or square=='b' then
		local B = {6,5,4}

		for i = 1, 3, 1 do
			local j = 4; local k = 1
			while j < 7 do
				temp_board[k][B[i]] = board[i][j]
				j = j+1
				k = k+1
			end
		end
		for i = 1, 3, 1 do
			for j = 4, 6, 1 do
				board[i][j] = temp_board[i][j] 
			end
		end
	elseif square == 'C' or square=='c' then
		local C = {}
		C[4] = 3; C[5] = 2; C[6] = 1

		for i = 4, 6, 1 do
			local j = 4; local k = 1
			while j < 7 do
				temp_board[j][C[i]] = board[i][k]
				j = j+1
				k = k+1
			end
		end
		for i = 4, 6, 1 do
			for j = 1, 3, 1 do
				board[i][j] = temp_board[i][j] 
			end
		end
	elseif square == 'D' or square=='d' then
		local D = {}
		D[4] = 6; D[5] = 5; D[6] = 4

		for i = 4, 6, 1 do
			local j = 4; local k = 1
			while j < 7 do
				temp_board[j][D[i]] = board[i][j]
				j = j+1
				k = k+1
			end
		end
		for i = 4, 6, 1 do
			for j = 4, 6, 1 do
				board[i][j] = temp_board[i][j] 
			end
		end
	end
end

function Board:_turn_CCW(square)
	local board		= _G[self.tableName]
	local temp_board = {}

	for i = 1, 6, 1 do
		temp_board[i] = {}
		for j = 1, 6, 1 do
			temp_board[i][j] = 1
		end
	end

	if square == 'A' or square == 'a' then
		local A = {3,2,1}

		for i = 1, 3, 1 do
			for j = 1, 3, 1 do
				temp_board[A[j]][i] = board[i][j]
			end
		end
		for i = 1, 3, 1 do
			for j = 1, 3, 1 do
				board[i][j] = temp_board[i][j] 
			end
		end
	elseif square == 'B' or square =='b' then
		local B = {4,5,6}

		for i = 1, 3, 1 do
			local j = 4; local k = 3
			while j < 7 do
				temp_board[k][B[i]] = board[i][j]
				j = j+1
				k = k-1
			end
		end
		for i = 1, 3, 1 do
			for j = 4, 6, 1 do
				board[i][j] = temp_board[i][j] 
			end
		end
	elseif square == 'C' or square =='c' then
		local C = {}
		C[4] = 1; C[5] = 2; C[6] = 3

		for i = 4, 6, 1 do
			local j = 6; local k = 1
			while j > 3 do
				temp_board[j][C[i]] = board[i][k]
				j = j-1
				k = k+1
			end
		end
		for i = 4, 6, 1 do
			for j = 1, 3, 1 do
				board[i][j] = temp_board[i][j] 
			end
		end
	elseif square == 'D' or square =='d' then
		--local D = {4 = 4, 5 = 5, 6 = 6}
		for i = 4, 6, 1 do
			local j = 4; local k = 6
			while j < 7 do
				temp_board[k][i] = board[i][j]
				j = j+1
				k = k-1
			end
		end
		for i = 4, 6, 1 do
			for j = 4, 6, 1 do
				board[i][j] = temp_board[i][j] 
			end
		end
	end
end

function Board:_check_5(player)
	local board = _G[self.tableName]
	local val = player+0
	--check rows
	for row = 1, 6, 1 do
		local temp_val = board[row][1]
		local count = 1
		
		for col =2, 6, 1 do 
			if temp_val == board[row][col] and board[row][col] == val then
				count = count + 1
			end
			temp_val = board[row][col]
		end
		if count > 4 then return true
		end
	end
	--check columns
	for col = 1, 6, 1 do
		local temp_val = board[1][col]
		local count = 1

		for row =1, 6, 1 do 
			if temp_val == board[row][col] and board[row][col] == val then
				count = count + 1
			end
			temp_val = board[row][col]
		end
		if count > 4 then return true
		end
	end
	--check left-right diagonals
	for sum = 5, -5, -1 do
		local diag = {}
		local count = 1
		--print('\n')
		for row = 1, 6,  1 do
			for col = 1, 6, 1 do
				if (row - col) == sum then
					table.insert(diag,board[row][col])
				end
			end
		end
		local firstValue = val
		for i,v in ipairs(diag) do
			if i>1 and firstValue == v and firstValue == val then
					count = count + 1
					--print ('count = '..count)
			end
			firstValue = v
		end
		if count > 4 then return true				
		end
	end
	--check right-left diagonals
	for sum = 2, 12, 1 do
		local diag = {}
		local count = 1
		for row = 1, 6, 1 do
			for col = 1, 6, 1 do
				if (row + col) == sum then
					table.insert(diag,board[row][col])
				end
			end
		end
		local firstValue = val
		for i,v in ipairs(diag) do
			if i>1 and firstValue == v and firstValue == val then
						count = count + 1
			end
			firstValue = v
		end
		if count > 4 then return true					
		end
	end
	return false
end

----[[
board = Board:create();
board:print();
board:set_stone(1,1,1)
board:set_stone(3,3,1)
board:set_stone(4,4,1)
board:set_stone(5,5,1)
board:set_stone(6,6,1)
board:print();
print(board:_check_5(1))
board:set_stone(2,6,2)
board:set_stone(3,5,2)
board:set_stone(4,4,2)
board:set_stone(5,3,2)
board:set_stone(6,2,2)
board:print()
--print(board:get_stone(6,4))
--print(board:get_stone(6,3))
--print(board:_check_5(1))
print(board:_check_5(2))
--[[
board:_turn_CCW("b")
board:print()
board:_turn_CW("a")
board:print()
board:_turn_CW("c")
board:print()
board:_turn_CCW("d")
board:print()
]]